﻿using CloudFranceTriple.Models;
using CloudFranceTriple.WebRole.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CloudFranceTriple.WebRole.Areas.Forum.Controllers
{
    public class TopicController : BaseController
    {
        private cloudfrAboq2RsDMEntities db = new cloudfrAboq2RsDMEntities();

        private readonly IWebSecurityWrapper _webSecurity;
        public TopicController()
        {
            this._webSecurity = new WebSecurityWrapper();
        }

        public TopicController(IWebSecurityWrapper webSecurity)
            : base(webSecurity)
        {
            this._webSecurity = webSecurity;
        }
        //
        // GET: /Forum/Topic/Index/68

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Index(int id)
        {
            ViewBag.Category_Id = id;
            var forumCategorySet = db.ForumCategorySet.Find(id);

            //Vérifier les droits d'accès par rapport à ForumSecurity
            if (!base.ForumIdAllowed.Contains(forumCategorySet.Forum_Id))
                ThrowSecurityException();

            ViewBag.ShowCreate = (UserRightLevelByCategoryId(id, User.Identity.IsAuthenticated) >= RightLevel.Author);
            ViewBag.SiteMapPath1 = HttpUtility.HtmlDecode(forumCategorySet.ForumSet.LabelForum);
            ViewBag.SiteMapPath2 = HttpUtility.HtmlDecode(forumCategorySet.LabelForumCategory);
            // TODO : pourquoi instancier un nouveau BaseController ?
            ViewBag.LocalizedUserRights = String.Format("({0})", CloudFranceTriple.WebRole.Models.RightLevel.GetRightLevelSelectListItems()[UserRightLevelByCategoryId(id, User.Identity.IsAuthenticated)].Text);

            return View(GetByCategoryNTopics(id));
        }

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult GetForumLastNTopics()
        {
            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListLastTopicTitle;

            return View("Index", base.GetForumLastNTopics());
        }

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult GetForumLastNPost()
        {
            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListLastPostTitle;

            return View("Index", base.GetForumLastNPost());
        }


        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult GetTopicsWithoutAnswer()
        {
            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListTopicWithoutAnswerTitle;

            return View("Index", base.GetTopicsWithoutAnswer());
        }

        // Il faut être connecté pour cela.
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult GetUnreadTopics()
        {
            if (!User.Identity.IsAuthenticated)
                ThrowSecurityException();

            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListUnreadTopicTitle;

            return View("Index", base.GetUnreadTopics());
        }

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult GetMostViewedTopics()
        {
            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListMostViewedTopicTitle;

            return View("Index", base.GetMostViewedTopics());
        }

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Search()
        {
            List<Int32> _forumTopicAllowed = this.ForumTopicAllowed;
            var AuthorList = (from msg in db.ForumPostSet
                              where _forumTopicAllowed.Contains(msg.ForumTopic_Id)
                              group msg by msg.PostMessage_Author into autors
                              select autors.Key).OrderBy(result => result).ToArray();

            return View(new ForumSearchCriteria { Keywords = String.Empty, Authors = AuthorList, ResultQuantity = 100 });
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Search(ForumSearchCriteria criteria)
        {
            ViewBag.SiteMapPath1 = String.Empty;
            ViewBag.SiteMapPath2 = String.Empty;
            ViewBag.LocalizedUserRights = String.Empty;
            ViewBag.ShowCreate = false;
            ViewBag.Title = CloudFranceTriple.WebRole.Properties.Resources.TopicListSearchTopicTitle;

            return View("Index", base.SearchByKeywordsAndAuthors(criteria));
        }
        // Exemple de liste de resultat de recherche sous forme de liste de message et non pas de liste de sujet
        // GET: /Forum/Post/
        //[Authorize(Roles = "RoleAdminForum")]
        //public ActionResult AllPost()
        //{
        //    ViewBag.SiteMapPath1 = "&nbsp;";
        //    ViewBag.SiteMapPath2 = "&nbsp;";
        //    ViewBag.SiteMapPath3 = "&nbsp;";
        //    ViewBag.Category_Id = 0;

        //    var forumpostset = db.ForumPostSet.Include(f => f.ForumTopicSet).OrderByDescending(p1 => p1.PostMessage_CreationDate);
        //    return View("Index", forumpostset.ToList());
        //}



        //
        // GET: /Forum/Topic/Create/5

        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Create(int id = 0)
        {
            ViewBag.Category_Id = id;
            if (id > 0)
                ViewBag.LabelForumCategory = HttpUtility.HtmlDecode(db.ForumCategorySet.Find(id).LabelForumCategory);

            //Liste des catId dont l'utilisateur a au moins des droits d'auteur.
            var catAuthor = new List<Int32>();
            foreach (Int32 catId in ForumCategoryAllowed)
                if (UserRightLevelByCategoryId(catId, User.Identity.IsAuthenticated) >= RightLevel.Author)
                    catAuthor.Add(catId);

            var CategoriesWithForumLabel = from ForumCategorySet cat in db.ForumCategorySet.Include("ForumSet")
                                           where catAuthor.Contains(cat.Id)
                                           orderby cat.ForumSet.LabelForum, cat.LabelForumCategory
                                           select new { id = cat.Id, LabelForumCategory = (cat.ForumSet.LabelForum + " > " + cat.LabelForumCategory) };

            ViewBag.ForumCategory_Id = new SelectList(CategoriesWithForumLabel, "Id", "LabelForumCategory", id);
            return View();
        }

        //
        // POST: /Forum/Topic/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Create(ForumTopicSet forumtopicset)
        {
            //Vérifier les droits d'accès par rapport à ForumSecurity
            if (!base.ForumIdAllowed.Contains(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).Forum_Id))
                ThrowSecurityException();

            if (ModelState.IsValid)
            {
                forumtopicset.AuthorForumTopic = User.Identity.Name;
                forumtopicset.CreationDateForumTopic = System.DateTime.UtcNow;
                forumtopicset.IsUnlocked = true;
                forumtopicset.NumberHasBeenSeenForumTopic = 0;
                forumtopicset.OrderForumTopic = 0;

                db.ForumTopicSet.Add(forumtopicset);
                db.SaveChanges();

                // Mettre à jour le compteur NumberOfTopic de la catégorie:
                var cat = db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id);
                cat.NumberOfTopic++;
                db.Entry(cat).State = System.Data.EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("Create", "Post", new { id = forumtopicset.Id, area = "Forum" });
            }
            ViewBag.Category_Id = forumtopicset.ForumCategory_Id;
            ViewBag.ForumCategory_Id = new SelectList(db.ForumCategorySet, "Id", "LabelForumCategory", forumtopicset.ForumCategory_Id);
            return View(forumtopicset);
        }

        //
        // GET: /Forum/Topic/Edit/5

        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Edit(int id = 0)
        {
            ForumTopicSet forumtopicset = db.ForumTopicSet.Find(id);
            if (forumtopicset == null)
            {
                return HttpNotFound();
            }

            //Vérifier les droits d'accès par rapport à ForumSecurity
            if (!base.ForumIdAllowed.Contains(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).Forum_Id))
                ThrowSecurityException();

            if (!CheckAutorRights(forumtopicset))
                ThrowSecurityException(forumtopicset);

            ViewBag.Category_Id = forumtopicset.ForumCategory_Id;
            ViewBag.LabelForumCategory = HttpUtility.HtmlDecode(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).LabelForumCategory);

            //Liste des catId dont l'utilisateur a au moins des droits d'auteur.
            var catAuthor = new List<Int32>();
            foreach (Int32 catId in ForumCategoryAllowed)
                if (UserRightLevelByCategoryId(catId, User.Identity.IsAuthenticated) >= RightLevel.Author)
                    catAuthor.Add(catId);

            var CategoriesWithForumLabel = from ForumCategorySet cat in db.ForumCategorySet.Include("ForumSet")
                                           where catAuthor.Contains(cat.Id)
                                           orderby cat.ForumSet.LabelForum, cat.LabelForumCategory
                                           select new { id = cat.Id, LabelForumCategory = (cat.ForumSet.LabelForum + " > " + cat.LabelForumCategory) };

            ViewBag.ForumCategory_Id = new SelectList(CategoriesWithForumLabel, "Id", "LabelForumCategory", forumtopicset.ForumCategory_Id);

            return View(forumtopicset);
        }

        //
        // POST: /Forum/Topic/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Edit(ForumTopicSet forumtopicset)
        {

            //Vérifier les droits d'accès par rapport à ForumSecurity
            if (!base.ForumIdAllowed.Contains(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).Forum_Id))
                ThrowSecurityException();

            if (!CheckAutorRights(forumtopicset))
                ThrowSecurityException(forumtopicset);

            if (ModelState.IsValid)
            {
                db.Entry(forumtopicset).State = EntityState.Modified;
                try
                {
                    db.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    ViewBag.Message = ex.Message;
                }
                return RedirectToAction("Index", "Topic", new { id = forumtopicset.ForumCategory_Id, area = "forum" });
            }
            ViewBag.Category_Id = forumtopicset.ForumCategory_Id;
            ViewBag.LabelForumCategory = HttpUtility.HtmlDecode(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).LabelForumCategory);



            //Liste des catId dont l'utilisateur a au moins des droits d'auteur.
            var catAuthor = new List<Int32>();
            foreach (Int32 catId in ForumCategoryAllowed)
                if (UserRightLevelByCategoryId(catId, User.Identity.IsAuthenticated) >= RightLevel.Author)
                    catAuthor.Add(catId);

            var CategoriesWithForumLabel = from ForumCategorySet cat in db.ForumCategorySet.Include("ForumSet")
                                           where catAuthor.Contains(cat.Id)
                                           orderby cat.ForumSet.LabelForum, cat.LabelForumCategory
                                           select new { id = cat.Id, LabelForumCategory = (cat.ForumSet.LabelForum + " > " + cat.LabelForumCategory) };

            ViewBag.ForumCategory_Id = new SelectList(CategoriesWithForumLabel, "Id", "LabelForumCategory", forumtopicset.ForumCategory_Id);

            return View(forumtopicset);
        }

        //
        // GET: /Forum/Topic/Delete/5

        [Authorize(Roles = "RoleAdminForum")]
        public ActionResult Delete(int id = 0)
        {
            ForumTopicSet forumtopicset = db.ForumTopicSet.Find(id);
            if (forumtopicset == null)
            {
                return HttpNotFound();
            }
            ViewBag.Category_Id = forumtopicset.ForumCategory_Id;
            ViewBag.LabelForumCategory = HttpUtility.HtmlDecode(db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id).LabelForumCategory);
            return View(forumtopicset);
        }

        //
        // POST: /Forum/Topic/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "RoleAdminForum")]
        public ActionResult DeleteConfirmed(int id)
        {
            ForumTopicSet forumtopicset = db.ForumTopicSet.Where(topic => topic.Id == id).Include("ForumPostSet").Include("PollSet").First();
            var postset = forumtopicset.ForumPostSet.ToList();
            var postNumber = postset.Count();
            var uc = new CloudFranceTriple.WebRole.Models.UsersContext();

            // Mettre à jour le compteur de post des utilisateurs qui ont postés dans le sujet effacé.
            foreach (ForumPostSet post in postset)
            {
                var userProfile = uc.UserProfiles.SingleOrDefault(u => u.UserName.ToLower() == post.PostMessage_Author.ToLower());
                if (userProfile != null)
                {
                    userProfile.ForumMessagePostedCounter--;
                    uc.Entry(userProfile).State = System.Data.EntityState.Modified;
                    uc.SaveChanges();
                }
            }

            db.ForumTopicSet.Remove(forumtopicset);
            db.SaveChanges();

            // Mettre à jour le compteur NumberOfTopic de la catégorie:
            var cat = db.ForumCategorySet.Find(forumtopicset.ForumCategory_Id);
            var _postInCat = db.ForumPostSet.Where(post => post.ForumTopicSet.ForumCategory_Id == cat.Id).ToList();
            if (_postInCat.Count > 0)
            {
                var newLastPost = db.ForumPostSet.Find(_postInCat.Max(post2 => post2.Id));
                if (newLastPost != null)
                {
                    cat.LastPostAuthor = newLastPost.PostMessage_Author;
                    cat.LastPostCreationDate = newLastPost.PostMessage_CreationDate;
                    cat.LastPostId = newLastPost.Id;
                    cat.LastPostTopicId = newLastPost.ForumTopic_Id;
                    cat.NumberOfTopic--;
                    cat.NumberOfMessage -= postNumber;
                }
                else
                {
                    cat.LastPostAuthor = null;
                    cat.LastPostCreationDate = null;
                    cat.LastPostId = null;
                    cat.LastPostTopicId = null;
                    cat.NumberOfTopic = 0;
                    cat.NumberOfMessage = 0;
                }
            }
            else
            {
                cat.LastPostAuthor = null;
                cat.LastPostCreationDate = null;
                cat.LastPostId = null;
                cat.LastPostTopicId = null;
                cat.NumberOfTopic = 0;
                cat.NumberOfMessage = 0;
            }

            db.Entry(cat).State = System.Data.EntityState.Modified;
            db.SaveChanges();

            return RedirectToAction("Index", "Topic", new { id = forumtopicset.ForumCategory_Id, area = "forum" });
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}